package com.wmx.mp.service.impl;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wmx.mp.config.MybatisPlusConfig;
import com.wmx.mp.entity.BasUser;
import com.wmx.mp.mapper.BasUserMapper;
import com.wmx.mp.service.IBasUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 用户信息业务层。
 *
 * @author wangMaoXiong
 * @version 1.0
 * @date 2023/3/4 8:55
 */
@Service
public class BasUserService implements IBasUserService {

    private static final String TABLE_NAME = "BAS_USER";

    @Resource
    private BasUserMapper basUserMapper;

    /**
     * 分页查询必须配置分页拦截器才会生效 {@link MybatisPlusConfig}，否则不会分页，而是查询全部。
     *
     * @param page    ：当前页，从1开始。
     * @param count   ：每页显示条数
     * @param keyword ：模糊查询的关键字
     * @return
     */
    @Override
    public IPage<BasUser> selectPage(Integer page, Integer count, String keyword) {
        // 根据 entity 条件，查询全部记录，queryWrapper 是实体对象封装操作类（可以为 null）
        // List<BasUser> userList = basUserMapper.selectList(null);

        Page<BasUser> pageDto = Page.of(page, count);
        QueryWrapper<BasUser> queryWrapper = new QueryWrapper();
        queryWrapper.like(StrUtil.isNotBlank(keyword), "user_Name", keyword)
                .or().like(StrUtil.isNotBlank(keyword), "email", keyword);
        // ==> Preparing: SELECT user_Id,user_name,EMAIL,BIRTHDAY,CREATE_TIME,UPDATE_TIME,IS_DELETE FROM bas_user WHERE IS_DELETE=2 ORDER BY UPDATE_TIME DESC LIMIT ? OFFSET ?
        // ==> Parameters: 5(Long), 5(Long)

        // ==> Preparing: SELECT user_Id,user_name,EMAIL,BIRTHDAY,CREATE_TIME,UPDATE_TIME,IS_DELETE FROM bas_user WHERE IS_DELETE=2 AND (user_Name LIKE ? OR email LIKE ?) ORDER BY UPDATE_TIME DESC LIMIT ?
        // ==> Parameters: %Billie%(String), %Billie%(String), 20(Long)
        IPage<BasUser> pages = basUserMapper.selectPage(pageDto, queryWrapper);
        return pages;
    }

    /**
     * 根据 ID 查询
     *
     * @param id ：主键ID
     * @return
     */
    @Override
    public BasUser selectById(Integer id) {
        // ==> Preparing: SELECT user_Id,user_name,EMAIL,BIRTHDAY,CREATE_TIME,UPDATE_TIME,IS_DELETE FROM bas_user WHERE user_Id IN ( ? ) AND IS_DELETE=2
        // ==> Parameters: 1(Integer)
        // <==    Columns: USER_ID, USER_NAME, EMAIL, BIRTHDAY, CREATE_TIME, UPDATE_TIME, IS_DELETE
        // <==        Row: 1, Jone Wang22, test1@wangmaoxiong.com, 1993-08-11, 2023-03-04 10:00:00, 2023-04-15 09:21:30.978, 2
        // <==      Total: 1
        BasUser basUser = basUserMapper.selectById(id);
        return basUser;
    }

    /**
     * 查询（根据ID 批量查询）
     *
     * @param ids ：主键ID集合
     * @return
     */
    @Override
    public List<BasUser> selectBatchIds(List<Integer> ids) {
        if (ObjectUtil.isEmpty(ids)) {
            return new ArrayList<>();
        }
        // ==> Preparing: SELECT user_Id,user_name,EMAIL,BIRTHDAY,CREATE_TIME,UPDATE_TIME,IS_DELETE FROM bas_user WHERE user_Id IN ( ? , ? , ? , ? , ? ) AND IS_DELETE=2
        // ==> Parameters: 1(Integer), 4(Integer), 5(Integer), 7(Integer), 9(Integer)
        // <==    Columns: USER_ID, USER_NAME, EMAIL, BIRTHDAY, CREATE_TIME, UPDATE_TIME, IS_DELETE
        // <==        Row: 1, Jone Wang22, test1@wangmaoxiong.com, 1993-08-11, 2023-03-04 10:00:00, 2023-04-15 09:21:30.978, 2
        // <==        Row: 4, Sandy, null, 1996-07-13, 2023-03-04 10:00:00, 2023-03-05 10:00:00, 2
        // <==        Row: 5, Billie, test5@baomidou.com, 1997-08-15, 2023-03-04 10:00:00, 2023-03-05 10:00:00, 2
        // <==        Row: 9, 张翠山, null, 1996-04-13, 2023-03-04 10:00:00, 2023-03-05 10:00:00, 2
        // <==      Total: 4
        List<BasUser> basUsers = basUserMapper.selectBatchIds(ListUtil.toList(ids));
        return basUsers;
    }

    /**
     * 查询（根据 columnMap 条件）
     *
     * @param columnMap ：表字段 map 对象，key 对应表中的列名，而不是实体对象的属性名。
     */
    @Override
    public List<BasUser> selectByMap(Map<String, Object> columnMap) {
        // SELECT user_Id,user_name,EMAIL,BIRTHDAY,CREATE_TIME,UPDATE_TIME,IS_DELETE FROM bas_user
        // WHERE email IS NULL AND user_Id = ? AND user_Name = ? AND IS_DELETE=2
        List<BasUser> basUsers = basUserMapper.selectByMap(columnMap);
        return basUsers;
    }

    /**
     * 根据 Wrapper 条件，查询总记录数
     */
    public Long selectCount() {
        // SELECT COUNT( * ) AS total FROM bas_user WHERE IS_DELETE=2
        Long selectCount = basUserMapper.selectCount(null);
        return selectCount;
    }

    /**
     * T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper)
     * 根据 entity 条件，查询一条记录。
     * 1、例如 qw.last("limit 1") 限制取一条记录, 注意：如果结果是多条数据，则会报异常：TooManyResultsException
     * 2、底层就是调用的 selectList，然后结果是1条时返回，超过1条时报错，没有时返回 null.
     *
     * @param id ：主键ID
     */
    @Override
    public BasUser selectOne(Integer id) {
        LambdaQueryWrapper<BasUser> queryWrapper = new QueryWrapper<BasUser>().lambda();
        queryWrapper.eq(BasUser::getUserId, id);
        // ==>  Preparing: SELECT user_Id,user_name,EMAIL,BIRTHDAY,CREATE_TIME,UPDATE_TIME,IS_DELETE FROM bas_user
        // WHERE IS_DELETE=2 AND (user_Id = ?) ORDER BY UPDATE_TIME DESC
        // ==> Parameters: 5(Integer)
        BasUser basUser = basUserMapper.selectOne(queryWrapper);
        return basUser;
    }

    /**
     * List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper
     * 1、根据 Wrapper 条件，查询全部记录
     * 2、注意：只返回第一个字段的值。
     * 3、queryWrapper 实体对象封装操作类，可以为 null或者为空，此时将查询全部。
     *
     * @param email
     * @return
     */
    public List<Object> selectObjs(String email) {
        LambdaQueryWrapper<BasUser> queryWrapper = new QueryWrapper<BasUser>().lambda();
        queryWrapper.eq(StrUtil.isNotBlank(email), BasUser::getEmail, email);
        // ==>  Preparing: SELECT user_Id,user_name,EMAIL,BIRTHDAY,CREATE_TIME,UPDATE_TIME,IS_DELETE FROM bas_user WHERE IS_DELETE=2 AND (EMAIL = ?) ORDER BY UPDATE_TIME DESC
        // ==> Parameters: test55@baomidou.com(String)
        // <==    Columns: USER_ID, USER_NAME, EMAIL, BIRTHDAY, CREATE_TIME, UPDATE_TIME, IS_DELETE
        // <==        Row: 1647026485095104514, 李元吉2, test55@baomidou.com, 1997-04-15, 2023-04-15 07:58:06.891, 2023-04-15 07:58:06.891, 2
        // <==        Row: 55, 李元吉, test55@baomidou.com, 1997-04-15, 2023-04-09 12:46:28.418, 2023-04-09 12:46:28.418, 2
        // <==      Total: 2
        List<Object> basUserList = basUserMapper.selectObjs(queryWrapper);
        // [1647026485095104514, 55]
        System.out.println(basUserList);
        return basUserList;
    }

    /**
     * 条件构造器 QueryWrapper 查询API。
     * 继承自 AbstractWrapper ,自身的内部属性 entity 也用于生成 where 条件及 LambdaQueryWrapper。
     * 1、QueryWrapper 参数中的 column 是数据库表的列名，而非实体对象的属性名。
     * 2、LambdaQueryWrapper 参数是实体属性名，会自动转数据库表的列名。
     *
     * @param keyword
     * @return
     */
    @Override
    public List<BasUser> queryWrapper(String keyword, Integer userId, String birthday, List<String> names) {
        // List<BasUser> queryWrapper = queryWrapperForLike(keyword);
        // List<BasUser> queryWrapper = queryWrapperForEq(userId);
        // List<BasUser> queryWrapper = queryWrapperForBetween(birthday);
        // List<BasUser> queryWrapper = queryWrapperForIn(names);
        // List<BasUser> queryWrapper = queryWrapperForGroupBy();
        // List<BasUser> queryWrapper = queryWrapperForOr();
        List<BasUser> queryWrapper = queryWrapperForExists();

        return queryWrapper;
    }

    /**
     * exists：拼接 EXISTS ( sql语句 )，例: exists("select id from table where age = 1")--->exists (select id from table where age = 1)
     * notExists：拼接 NOT EXISTS ( sql语句 )，例: notExists("select id from table where age = 1")--->not exists (select id from table where age = 1)
     * last：无视优化规则直接拼接到 sql 的最后，只能调用一次,多次调用以最后一次为准 有sql注入的风险,请谨慎使用。
     * * 例: last("limit 1")
     *
     * @return
     */
    private List<BasUser> queryWrapperForExists() {
        // 查询条件构造器
        QueryWrapper<BasUser> queryWrapper = new QueryWrapper<>();
        // SELECT user_Id,user_name,EMAIL,BIRTHDAY,CREATE_TIME,UPDATE_TIME,IS_DELETE FROM bas_user
        // WHERE IS_DELETE=2 AND (EXISTS (SELECT 1 FROM (SELECT user_name FROM bas_user GROUP BY user_name HAVING COUNT(1) > 1) t
        // WHERE t.user_name = BAS_USER.user_name )) ORDER BY UPDATE_TIME DESC
        queryWrapper.exists("SELECT 1 FROM (SELECT user_name FROM bas_user GROUP BY user_name HAVING COUNT(1) > 1) " +
                "t WHERE t.user_name = " + TABLE_NAME + ".user_name ");
        List<BasUser> userList = basUserMapper.selectList(queryWrapper);
        return userList;
    }

    /**
     * or：主动调用or表示紧接着下一个方法不是用and连接!(不调用or则默认为使用and连接)
     * * 拼接 OR：例: eq("id",1).or().eq("name","老王")--->id = 1 or name = '老王'
     * * OR 嵌套：例: or(i -> i.eq("name", "李白").ne("status", "活着"))--->or (name = '李白' and status <> '活着')
     * and：AND 嵌套，例: and(i -> i.eq("name", "李白").ne("status", "活着"))--->and (name = '李白' and status <> '活着')
     * nested：正常嵌套 不带 AND 或者 OR
     * * 例: nested(i -> i.eq("name", "李白").ne("status", "活着"))--->(name = '李白' and status <> '活着')
     *
     * @return
     */
    private List<BasUser> queryWrapperForOr() {
        // 查询条件构造器
        QueryWrapper<BasUser> queryWrapper = new QueryWrapper<>();
        // 参数中的 column 是数据库表的列名，而非实体对象的属性名。
        // SELECT user_Id,user_name,EMAIL,BIRTHDAY,CREATE_TIME,UPDATE_TIME,IS_DELETE FROM bas_user
        // WHERE IS_DELETE=2 AND (user_name LIKE ? OR user_name IS NULL OR (email LIKE ? AND email IS NOT NULL)) ORDER BY UPDATE_TIME DESC
        queryWrapper.likeRight("user_name", "张").or().isNull("user_name")
                .or(qw -> qw.likeLeft("email", "@wangmaoxiong.com").isNotNull("email"));

        List<BasUser> userList = basUserMapper.selectList(queryWrapper);
        return userList;
    }

    /**
     * select：设置查询字段
     * * 例: select("id", "name", "age")
     * * 例: select(i -> i.getProperty().startsWith("test"))
     * groupBy：分组：GROUP BY 字段, ...，例: groupBy("id", "name")--->group by id,name
     * having：HAVING ( sql语句 )，
     * * 例: having("sum(age) > 10")--->having sum(age) > 10
     * * 例: having("sum(age) > {0}", 11)--->having sum(age) > 11
     * orderByAsc：排序：ORDER BY 字段, ... ASC，例: orderByAsc("id", "name")--->order by id ASC,name ASC
     * orderByDesc：排序：ORDER BY 字段, ... DESC，例: orderByDesc("id", "name")--->order by id DESC,name DESC
     * orderBy：排序：ORDER BY 字段, ...，例: orderBy(true, true, "id", "name")--->order by id ASC,name ASC
     * 条件构造器中指定排序后，就会覆盖实体对象属性上的排序注解。
     *
     * @return
     */
    private List<BasUser> queryWrapperForGroupBy() {
        // 查询条件构造器
        QueryWrapper<BasUser> groupByQueryWrapper = new QueryWrapper<>();
        // 用指定的排序字段覆盖掉实体对象属性上的排序注解，否则排序字段不在分组中时sql报错。
        // SELECT user_name FROM bas_user WHERE IS_DELETE=2 GROUP BY user_name HAVING count(1)>1 ORDER BY user_name ASC
        groupByQueryWrapper.select("user_name").groupBy("user_name").having("count(1)>1")
                .orderBy(true, true, "user_name");

        List<BasUser> userList = basUserMapper.selectList(groupByQueryWrapper);
        List<String> collect = userList.stream().map(basUser -> basUser.getUserName()).collect(Collectors.toList());

        QueryWrapper<BasUser> queryWrapper = new QueryWrapper<>();
        // SELECT user_Id,user_name,EMAIL,BIRTHDAY,CREATE_TIME,UPDATE_TIME,IS_DELETE
        // FROM bas_user WHERE IS_DELETE=2 AND (user_name IN (?)) ORDER BY birthday ASC
        queryWrapper.in("user_name", collect).orderByAsc("birthday");
        userList = basUserMapper.selectList(queryWrapper);

        return userList;
    }

    /**
     * in：字段 IN (v0, v1, ...)，例: in("age",{1,2,3})--->age in (1,2,3)
     * notIn：字段 NOT IN (v0, v1, ...)，例: notIn("age",{1,2,3})--->age not in (1,2,3)
     * inSql：字段 IN ( sql语句 )
     * * 例: inSql("age", "1,2,3,4,5,6")--->age in (1,2,3,4,5,6)
     * * 例: inSql("id", "select id from table where id < 3")--->id in (select id from table where id < 3)
     * notInSql：字段 NOT IN ( sql语句 )
     * * 例: notInSql("age", "1,2,3,4,5,6")--->age not in (1,2,3,4,5,6)
     * * 例: notInSql("id", "select id from table where id < 3")--->id not in (select id from table where id < 3)
     *
     * @param names
     * @return
     */
    private List<BasUser> queryWrapperForIn(List<String> names) {
        // 查询条件构造器
        QueryWrapper<BasUser> queryWrapper = new QueryWrapper<>();
        // 参数中的 column 是数据库表的列名，而非实体对象的属性名。
        // SELECT user_Id,user_name,EMAIL,BIRTHDAY,CREATE_TIME,UPDATE_TIME,IS_DELETE FROM bas_user
        // WHERE IS_DELETE=2 AND (user_name IN (?,?,?) AND user_name NOT IN ('admin','root')) ORDER BY UPDATE_TIME DESC
        queryWrapper.in("user_name", names).notInSql("user_name", "'admin','root'");
        // 根据 entity 条件，查询全部记录，queryWrapper 是实体对象封装操作类（可以为 null）
        List<BasUser> userList = basUserMapper.selectList(queryWrapper);
        return userList;
    }

    /**
     * between：BETWEEN 值1 AND 值2，例: between("age", 18, 30)--->age between 18 and 30
     * notBetween：NOT BETWEEN 值1 AND 值2，例: notBetween("age", 18, 30)--->age not between 18 and 3
     * isNull：例: isNull("name")--->name is null
     * isNotNull：例: isNotNull("name")--->name is not null
     *
     * @param birthday
     * @return
     */
    private List<BasUser> queryWrapperForBetween(String birthday) {
        // 查询条件构造器
        QueryWrapper<BasUser> queryWrapper = new QueryWrapper<>();
        // 参数中的 column 是数据库表的列名，而非实体对象的属性名。
        // SELECT user_Id,user_name,EMAIL,BIRTHDAY,CREATE_TIME,UPDATE_TIME,IS_DELETE
        // FROM bas_user WHERE IS_DELETE=2 AND (birthday IS NOT NULL AND birthday BETWEEN ? AND ?) ORDER BY UPDATE_TIME DESC
        queryWrapper.isNotNull("birthday")
                .between("birthday", birthday, new Date());
        // 根据 entity 条件，查询全部记录，queryWrapper 是实体对象封装操作类（可以为 null）
        List<BasUser> userList = basUserMapper.selectList(queryWrapper);
        return userList;
    }

    /**
     * eq：等于 =，例: eq("name", "老王")--->name = '老王'
     * ne：不等于 <>，例: ne("name", "老王")--->name <> '老王'
     * gt：大于 >，例: gt("age", 18)--->age > 18
     * ge：大于等于 >=，例: ge("age", 18)--->age >= 18
     * lt：小于 <，例: lt("age", 18)--->age < 18
     * le：小于等于 <=，例: le("age", 18)--->age <= 18
     *
     * @param userId
     * @return
     */
    private List<BasUser> queryWrapperForEq(Integer userId) {
        // 查询条件构造器
        QueryWrapper<BasUser> queryWrapper = new QueryWrapper<>();
        // 参数中的 column 是数据库表的列名，而非实体对象的属性名。
        queryWrapper.eq(userId != null, "user_id", userId);
        // 根据 entity 条件，查询全部记录，queryWrapper 是实体对象封装操作类（可以为 null）
        List<BasUser> userList = basUserMapper.selectList(queryWrapper);
        return userList;
    }

    /**
     * like：LIKE '%值%'
     * likeLeft：LIKE '%值'
     * likeRight：LIKE '值%'
     * notLike：NOT LIKE '%值%'
     * notLikeLeft：NOT LIKE '%值'
     * notLikeRight：NOT LIKE '值%'
     *
     * @param keyword
     * @return
     */
    private List<BasUser> queryWrapperForLike(String keyword) {
        // 查询条件构造器
        QueryWrapper<BasUser> queryWrapper = new QueryWrapper<>();
        // 查询的列名是数据库表的列名，而不是实体对象的属性名。
        if (StringUtils.isNotBlank(keyword)) {
            /**
             * <pre>
             *   SELECT user_Id,user_name,EMAIL,BIRTHDAY,CREATE_TIME,UPDATE_TIME,IS_DELETE
             *   FROM  bas_user WHERE IS_DELETE=2 AND (user_name LIKE ? OR email LIKE ?) ORDER BY UPDATE_TIME DESC
             * </pre>
             */
            queryWrapper.like("user_name", keyword.trim())
                    .or().like("email", keyword.trim());
        }
        // 根据 entity 条件，查询全部记录，queryWrapper 是实体对象封装操作类（可以为 null）
        List<BasUser> userList = basUserMapper.selectList(queryWrapper);
        return userList;
    }

    /**
     * LambdaQueryWrapper：Lambda 语法使用 Wrapper，使用实体对象属性名自动映射数据库表列名，而不用写死列名。
     * * 可以通过 new QueryWrapper().lambda() 方法获取，也可以 new LambdaQueryWrapper。
     * * 使用完全等价 QueryWrapper。
     *
     * @param keyword
     * @param userId
     * @param birthday
     * @param names
     * @return
     */
    @Override
    public List<BasUser> lambdaQueryWrapper(String keyword, Integer userId, String birthday, List<String> names) {
        List<BasUser> queryWrapper = lambdaQueryWrapperForLike(keyword);
        return queryWrapper;
    }

    /**
     * 等价 {@link BasUserService#queryWrapperForLike(java.lang.String)}
     *
     * @param keyword
     * @return
     */
    private List<BasUser> lambdaQueryWrapperForLike(String keyword) {
        // 查询条件构造器
        LambdaQueryWrapper<BasUser> lambdaQueryWrapper = new QueryWrapper<BasUser>().lambda();
        // 查询的列名是数据库表的列名，而不是实体对象的属性名。
        if (StringUtils.isNotBlank(keyword)) {
            // SELECT user_Id,user_name,EMAIL,BIRTHDAY,CREATE_TIME,UPDATE_TIME,is_delete FROM bas_user
            // WHERE is_delete=2 AND (user_name LIKE ? OR EMAIL LIKE ?) ORDER BY UPDATE_TIME DESC
            lambdaQueryWrapper.like(BasUser::getUserName, keyword.trim()).or().like(BasUser::getEmail, keyword.trim());
        }
        // 根据 entity 条件，查询全部记录，queryWrapper 是实体对象封装操作类（可以为 null）
        List<BasUser> userList = basUserMapper.selectList(lambdaQueryWrapper);
        return userList;
    }

    /**
     * 查询表中一共有多少条数据
     *
     * @return
     */
    @Override
    public int countAll() {
        return basUserMapper.countAll();
    }

    /**
     * 批量新增保存.
     * BaseMapper 默认默认没有提供批量插入的方法，{@link ServiceImpl} 才有批量操作的方法。
     * int insert(T entity)：插入一条记录，entity 实体对象，返回影响的条数。
     * 如果某个属性没有指定，或者指定值为null，则属性名称不会出现在 insert into sql中。
     * 可以直接从新增后的实体中获取自动填充的主键，而不用再额外的配置。
     *
     * @param basUserList ：待新增保存的数据
     */
    public void insertList(List<BasUser> basUserList) {
        for (BasUser basUser : basUserList) {
            // ==> Preparing: INSERT INTO bas_user ( user_Id, user_name, EMAIL, BIRTHDAY, CREATE_TIME, UPDATE_TIME, IS_DELETE ) VALUES ( ?, ?, ?, ?, ?, ?, ? )
            // ==> Parameters: 1644924768589279233(Long), 李世民(String), test54@wangmaoxiong.com(String), 1993-02-11 00:00:00.0(Timestamp), 2023-04-09 12:46:28.418(Timestamp), 2023-04-09 12:46:28.418(Timestamp), 2(Integer)
            // <== Updates: 1
            int insert = basUserMapper.insert(basUser);
            // insert=1,user_id=1647026476144459777
            // insert=1,user_id=1644924768589279233
            System.out.println("insert count=" + insert + ",user_id=" + basUser.getUserId());
        }
    }

    /**
     * 更新保存: int updateById(@Param(Constants.ENTITY) T entity)
     * 1、返回影响的条数。
     * 2、如果某个属性没有指定，或者指定值为null，则属性名称不会出现在 UPDATE SET xxx 更新 sql中。
     *
     * @param basUserList ：待更新保存的数据
     */
    public void updateById(List<BasUser> basUserList) {
        for (BasUser basUser : basUserList) {
            // ==> Preparing: UPDATE bas_user SET user_name=?, EMAIL=?, UPDATE_TIME=? WHERE user_Id=? AND IS_DELETE=2
            // ==> Parameters: Jone Wang(String), test1@wangmaoxiong.com(String), 2023-04-15 08:32:33.914(Timestamp), 1(Long)
            // <== Updates: 1
            //
            // ==> Preparing: UPDATE bas_user SET user_name=?, BIRTHDAY=?, CREATE_TIME=?, UPDATE_TIME=? WHERE user_Id=? AND IS_DELETE=2
            // ==> Parameters: Jack Li(String), 1994-09-21 00:00:00.0(Timestamp), 2023-03-04 10:00:00.0(Timestamp), 2023-04-15 08:32:33.914(Timestamp), 2(Long)
            // <== Updates: 1
            int count = basUserMapper.updateById(basUser);
            System.out.println(count);
        }
    }

    /**
     * int update(T entity, Wrapper<T> updateWrapper)
     * 根据 whereEntity 条件，更新记录
     * entity        实体对象 (set 条件值,可以为 null)
     * updateWrapper 实体对象封装操作类（可以为 null,里面的 entity 用于生成 where 语句
     *
     * @param basUser
     */
    public void update(BasUser basUser) {
        LambdaQueryWrapper<BasUser> lambdaQueryWrapper = new QueryWrapper<BasUser>().lambda();
        lambdaQueryWrapper.eq(BasUser::getUserId, basUser.getUserId())
                .eq(BasUser::getUpdateTime, basUser.getUpdateTime())
                .eq(BasUser::getIsDelete, 2);
        // ==> Preparing: UPDATE bas_user SET user_name=?, EMAIL=?, BIRTHDAY=?, UPDATE_TIME=? WHERE IS_DELETE=2 AND (user_Id = ? AND UPDATE_TIME = ? AND IS_DELETE = ?)
        // ==> Parameters: Tom2(String), test31@baomidou.com(String), 1995-06-05 00:00:00.0(Timestamp), 2023-03-05 10:00:00.0(Timestamp), 3(Long), 2023-03-05 10:00:00.0(Timestamp), 2(Integer)
        // <== Updates: 1
        int count = basUserMapper.update(basUser, lambdaQueryWrapper);
        System.out.println(count);
    }

    /**
     * 批量删除
     * 1、当全局配置了以下属性时，则表示启用了逻辑删除。
     * <pre>
     * mybatis-plus:
     *   global-config:
     *     db-config:
     *       # 全局的 entity 的逻辑删除字段属性名(逻辑删除下有效,默认值：null)。
     *       # 当配置逻辑删除字段，且数据库表有此字段时，删除操作默认都会做逻辑删除，查询时默认也只会查询未逻辑删除的值。
     *       logic-delete-field: isDelete
     *       logic-delete-value: 1 # 逻辑已删除值(逻辑删除下有效,默认值：1)
     *       logic-not-delete-value: 2 # 逻辑未删除值(逻辑删除下有效,默认值：0)
     * </pre>
     *
     * @param basUserList ：待删除的数据
     */
    public void deleteBatchIds(List<BasUser> basUserList) {
        // 删除（根据ID或实体 批量删除），返回影响的条数.
        // @param idList 主键ID列表或实体列表(不能为 null 以及 empty)
        int i = basUserMapper.deleteBatchIds(basUserList);
    }

    /**
     * 根据主键 ID 删除：int deleteById(Serializable id)，值不能是 Null，否则空指针异常。
     * 根据实体(ID)删除：int deleteById(T entity);，值不能是 Null，否则异常。
     *
     * @param id 主键ID
     */
    @Override
    public void deleteById(Integer id) {
        // 返回影响的条数.
        //  UPDATE bas_user SET IS_DELETE=1 WHERE user_Id=?  AND IS_DELETE=2
        int i = basUserMapper.deleteById(id);
        System.out.println(i);
    }

    /**
     * 根据主键 ID 删除：int deleteById(Serializable id),值不能是 Null，否则异常。
     * 根据实体(ID)删除：int deleteById(T entity);值不能是 Null，否则异常。
     *
     * @param basUser ：实体对象
     */
    @Override
    public void deleteById(BasUser basUser) {
        // ==> Preparing: UPDATE bas_user SET IS_DELETE=1 WHERE user_Id=? AND IS_DELETE=2
        // ==> Parameters: 8(Long)
        int i = basUserMapper.deleteById(basUser);
        System.out.println(i);
    }

    /**
     * int deleteByMap(Map<String, Object> columnMap)
     * 1、根据 columnMap 条件，删除记录。
     * 2、注意当 map 为空或者为null，无法拼接where条件时，如果配置了 BlockAttackInnerInterceptor(防全表更新与删除插件),则操作会被阻止。否则全表删除。
     * 拦截插件阻止全表删除时会报错：com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: Prohibition of table update operation
     *
     * @param columnMap: 表字段 map 对象，key是表中的列名，而不是实体对象的属性名。
     */
    @Override
    public void deleteByMap(Map<String, Object> columnMap) {
        // ==> Preparing: UPDATE bas_user SET IS_DELETE=1 WHERE email = ? AND user_Id = ? AND user_Name = ? AND IS_DELETE=2
        // ==> Parameters: test11@wangmaoxiong.com(String), 11(Integer), 张无忌(String)
        int i = basUserMapper.deleteByMap(columnMap);
        System.out.println(i);
    }

    /**
     * 根据 entity 条件，删除记录
     * <p>
     * int delete(Wrapper<T> queryWrapper)
     * 1、queryWrapper 实体对象封装操作类（可以为 null,里面的 entity 用于生成 where 语句）
     * 2、注意当 queryWrapper 为空或者为null，无法拼接where条件时，如果配置了 BlockAttackInnerInterceptor(防全表更新与删除插件),则操作会被阻止。否则全表删除。
     * 拦截插件阻止全表删除时会报错：com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: Prohibition of table update operation
     */
    @Override
    public void deleteByQuery(String email) {
        LambdaQueryWrapper<BasUser> lambdaQueryWrapper = new QueryWrapper<BasUser>().lambda();
        lambdaQueryWrapper.eq(StrUtil.isNotBlank(email), BasUser::getEmail, email);
        // ==> Preparing: UPDATE bas_user SET IS_DELETE=1 WHERE IS_DELETE=2 AND (EMAIL = ?)
        // ==> Parameters: test7@wangmaoxiong.com(String)
        int delete = basUserMapper.delete(lambdaQueryWrapper);
        System.out.println(delete);
    }
}

